package com.chao.yyks.modular.score.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chao.common.util.DateUtile;
import com.chao.common.util.ListUtile;
import com.chao.common.util.RequestUtile;
import com.chao.common.util.StrUtile;
import com.chao.common.util.exception.SysException;
import com.chao.common.util.reaction.PageList;
import com.chao.yyks.modular.hearing.service.EnHearingService;
import com.chao.yyks.modular.paragraph.bean.EnParagraph;
import com.chao.yyks.modular.paragraph.service.EnParagraphService;
import com.chao.yyks.modular.problem.bean.EnProblemOption;
import com.chao.yyks.modular.ranking.bean.EnRanking;
import com.chao.yyks.modular.ranking.mapper.EnRankingMapper;
import com.chao.yyks.modular.score.bean.EnAnswer;
import com.chao.yyks.modular.score.bean.EnScore;
import com.chao.yyks.modular.score.mapper.EnAnswerMapper;
import com.chao.yyks.modular.score.mapper.EnScoreMapper;
import com.chao.yyks.modular.score.service.EnScoreService;
import com.chao.yyks.modular.studentMsg.mapper.EnStudentMsgMapper;
import com.chao.yyks.modular.sys.bean.EnClasssType;
import com.chao.yyks.modular.sys.bean.EnStudent;
import com.chao.yyks.modular.sys.mapper.EnClasssTypeMapper;
import com.chao.yyks.modular.sys.mapper.EnStudentMapper;
import com.chao.yyks.util.QwenLong;
import com.chao.yyks.util.SpliteText;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 成绩ServiceImpl
 * chao
 * 2024-09-13
 */
@Slf4j
@Service
public class EnScoreServiceImpl implements EnScoreService {

	/**
	 * 成绩Mapper
	 */
	@Autowired
	private EnScoreMapper enScoreMapper;

	/**
	 * 成绩答题Mapper
	 */
	@Autowired
	private EnAnswerMapper enAnswerMapper;

	/**
	 * 问题数量配置Mapper
	 */
	@Autowired
	private EnClasssTypeMapper enClasssTypeMapper;

	/**
	 * 学生Mapper
	 */
	@Autowired
	private EnStudentMapper enStudentMapper;

	/**
	 * 听力Service
	 */
	@Autowired
	private EnHearingService enHearingService;

	/**
	 * 阅读文章Service
	 */
	@Autowired
	private EnParagraphService enParagraphService;

	/**
	 * 学生排名Mapper
	 */
	@Autowired
	private EnRankingMapper enRankingMapper;

	/**
	 * 学生留言Mapper
	 */
	@Autowired
	private EnStudentMsgMapper enStudentMsgMapper;

	/**
	 * 修改成绩
	 */
	@Override
	@Transactional
	public void updateEnScore(String scoreId){
		EnStudent enStudent = enStudentMapper.selectEnStudentByStudentId(RequestUtile.getLoginUserId());
		if(null == enStudent){
			throw new SysException("登录账号异常,请重新登录或联系老师!");
		}
		EnScore enScorePojo = enScoreMapper.selectEnScoreByScoreId(scoreId);
		if(null == enScorePojo){
		    throw new SysException("记录不存在!");
		}
		if(!"1".equals(enScorePojo.getScoreState())){
			throw new SysException("当前考试已经提交答案,请不要重复提交!");
		}
		String upType = enScorePojo.getProblemUpType();
		List<EnAnswer> answerList = enAnswerMapper.selectEnAnswerByList(JSONObject.parseObject("{\"scoreId\":\""+enScorePojo.getScoreId()+"\"}")).getList();
		List<EnClasssType> typeList = enClasssTypeMapper.selectEnClasssTypeByList(enStudent.getClasssId());
		float scoreAll = 0; // 总得分
		Map<String,EnClasssType> tm = typeList.stream().filter(t->upType.equals(t.getProblemUpType())).collect(Collectors.toMap(EnClasssType::getProblemType,j->j));
		Map<String,List<EnAnswer>> am = answerList.stream().collect(Collectors.groupingBy(EnAnswer::getProblemType));
		for (Map.Entry<String,List<EnAnswer>> as:am.entrySet()){
			EnClasssType type = tm.get(as.getKey());
			// 每题分值 = (大类总分 * 小类权重 ) / 小类问题数 例如 口语题总分100
			float fz = Float.parseFloat(type.getProblemScore());
			float score = 0F; // 小分类得分
			int size = 0;
			for (EnAnswer answer : as.getValue()){
				// 口语题 根据答题数量平均
				if("4".equals(upType) && !StrUtile.isEmpty(answer.getAnswerScore())){
					size ++;
					score += Float.parseFloat(answer.getAnswerScore()) * (fz / 100);
				}
				if(StrUtile.isEmpty(answer.getAnswerScore())){
					answer.setAnswerScore("0");
				}
				// 选择题选择正确
				if("1".equals(answer.getAnswerTrue())){
					answer.setAnswerScore(new DecimalFormat("#.#").format(fz));
				}
				// 作文点评
				if(!StrUtile.isEmpty(answer.getAnswerText()) && "6".equals(upType)){
					// 这里有一篇参考范文：
					String sss = (StrUtile.isEmpty(answer.getProblemAnswer())?"":"这里有一篇参考范文："+answer.getProblemAnswer()+ "\n请以范文为标准，")+"按照下列维度对作业评分并举例说明需要改进的地方:" +
							"\n1.内容：作文内容与范文主题内容一致，围绕主题进行了充分的阐述。2分\n2.衔接与连贯：行文连贯，段落之间过渡自然，句子之间衔接紧密，恰当使用了衔接性词语，表达因果关系，转折关系，" +
							"递进关系等逻辑关系。2分\n3.词汇：准确恰当地使用词汇。既包含频率高的词，也包含使用频率较低的复杂词汇，表达抽象意义。2分\n4.句法：灵活准确地使用不同的语法结构。包括简单句型，也包括复杂的句型。" +
							"语法错误少。2.5分\n作业:"+answer.getAnswerText()+
							"\n返回格式为纯json对象字符串,不要包含数组,饱含a1(内容评价),a2(衔接与连贯评价),a3(词汇评价),a4(句法评价),a5(内容得分),a6(衔接与连贯得分),a7(词汇得分),a8(句法得分)," +
							"corrections(润色修正),score(总得分)字段";
					String str = QwenLong.callWithMessage(sss);
					log.info("英文作文AI点评关键字:{}",sss);
					if(StrUtile.isEmpty(str)){
						throw new SysException("英文作文AI点评失败,请稍后再试!");
					}
					int ch = SpliteText.splitfuhaoCh(answer.getAnswerText());
					log.info("作文AI点评:{}",str);
					str = str.substring(str.indexOf("{"));
					str = str.substring(0,str.lastIndexOf("}")+1);
					JSONObject json = JSON.parseObject(str);
					fz = 0;
					StringBuilder sb = new StringBuilder();
					sb.append("内容评价:").append(json.getString("a1")).append("\t得分:").append(json.getString("a5")).append("\n")
							.append("衔接与连贯评价:").append(json.getString("a2")).append("\t得分:").append(json.getString("a6")).append("\n")
							.append("词汇评价:").append(json.getString("a3")).append("\t得分:").append(json.getString("a7")).append("\n")
							.append("句法评价:").append(json.getString("a4")).append("\t得分:").append(json.getString("a8"));
					EnParagraph enParagraph = enParagraphService.selectEnParagraphByParagraphId(answer.getParagraphId());

					fz += json.getFloat("a5") + json.getFloat("a6") + json.getFloat("a7") + json.getFloat("a8");
					if(!StrUtile.isEmpty(enParagraph.getParagraphTitle())){
						sb.append("\n命中关键词:");
						String[] keys = enParagraph.getParagraphTitle().split("\n");
						float cf = 0;
						for (int i = 1; i < keys.length; i++) {
							if(answer.getAnswerText().toLowerCase().contains(keys[i].trim().toLowerCase())){
								fz += 0.1;
								cf += 0.1;
								sb.append(keys[i].trim()).append("\t");
							}
						}
						if(cf == 0){
							sb.append("无,得分:0");
						}else {
							sb.append("得分:").append(new DecimalFormat("#.##").format(cf));
						}
					}
					if(ch < 80){
						sb.append("\n词汇数:").append(ch).append(",扣1分");
						fz -= 1;
					}
					if(ch < 120){
						sb.append("\n词汇数:").append(ch).append(",扣0.5分");
						fz -= 0.5;
					}
					answer.setAnswerComment(sb.toString());
					String corrections = json.getString("corrections").replace("{","").replace("}","").trim();
					answer.setAnswerOptimize(StrUtile.isEmpty(corrections)?"整体表达清晰，无需润色！":corrections);
					answer.setAnswerScore(new DecimalFormat("#.##").format(fz));
				}
				// 翻译点评
				if(!StrUtile.isEmpty(answer.getAnswerText()) && "5".equals(upType)){
					String sss = (StrUtile.isEmpty(answer.getProblemAnswer())?"":"这里有一篇参考范文："+answer.getProblemAnswer()+ "请以范文为标准，")+"评价这段译文:" +answer.getAnswerText()+
							"是否准确表达了范文的意思，逻辑是否清晰，行文是否连贯，用词是否贴切，是否有语法错误，并以百分制为其评分，然后修正所有语法错误。返回格式为纯json对象字符串," +
							"不要包含数组,包含a1(准确性评语),a2(逻辑性评语),a3(连贯性评语),a4(用词恰当性评语),a5(语法错误评语),corrections(修正),score(得分)字段";
					log.info("翻译点评关键字:{}",sss);
					String str = QwenLong.callWithMessage(sss);
					if(StrUtile.isEmpty(str)){
						throw new SysException("翻译AI点评失败,请稍后再试!");
					}
					log.info("翻译AI点评:{}",str);
					str = str.substring(str.indexOf("{"));
					str = str.substring(0,str.lastIndexOf("}")+1);
					JSONObject json = JSON.parseObject(str);
					int sc = json.getInteger("score");
					if(!ListUtile.isEmpty(answer.getOptionList())){
						for (EnProblemOption option : answer.getOptionList()) {
							if(!answer.getAnswerText().toLowerCase().contains(option.getOptionTitle().toLowerCase())){
								sc -= 2;
							}
						}
					}
					StringBuilder sb = new StringBuilder();
					sb.append("准确性:").append(json.getString("a1")+"\n")
							.append("逻辑性:").append(json.getString("a2")+"\n")
							.append("连贯性:").append(json.getString("a3")+"\n")
							.append("用词恰当性:").append(json.getString("a4")+"\n")
							.append("语法错误:").append(json.getString("a5"));
					answer.setAnswerComment(sb.toString());
					String corrections = json.getString("corrections");
					answer.setAnswerOptimize(StrUtile.isEmpty(corrections)?"无语法错误,无需修正！":corrections);
					answer.setAnswerScore(new DecimalFormat("#.##").format(Math.max(sc, 0) * (fz / 100)));
				}
				if(!"4".equals(upType)) {
					score += Float.parseFloat(answer.getAnswerScore());
				}
				enAnswerMapper.updateEnAnswer(answer);
			}
			if("4".equals(upType)){
                try {
                	if(size > 1){
						scoreAll += score / size;
					} else {
						scoreAll += score;
					}
				}catch (Exception e){
					scoreAll += 0;
				}
			}else {
				// 总分 = 小分类得分之和
				scoreAll += score;
			}
		}
		enScorePojo.setScore(new DecimalFormat("#.##").format(scoreAll));
		enScorePojo.setScoreState("2");
		enScoreMapper.updateEnScore(enScorePojo);


		EnRanking ranking = enRankingMapper.selectEnRankingByStudentId(enScorePojo.getStudentId());
		JSONObject score = enScoreMapper.selectEnScore(enScorePojo.getStudentId());
		// 做题次数加分  每周 做题次数总分15分  所有题目都做 每次 0.75 只做阅读 每次 3.75 只做 听力口语 每次 1.875 做题次数按周平均
		long num = DateUtile.calculateWeeksBetween("2024-10-13");
		List<JSONObject> list = enRankingMapper.selectEnTypeNum(enScorePojo.getStudentId());
		double size = list.stream().mapToDouble(j->j.getDouble("scoreNum")).sum();
		if("20241016213730459620,20241016213831307707,20241016213933804527,20241016214028265393".contains(enStudent.getClasssId())){
			size = (size/num*3.75);
		}else if ("20241016215039448906,20241016215052239812".contains(enStudent.getClasssId())){
			size = (size/num*1.875);
		}else {
			size = (size/num*0.75);
		}
		// 留言加分
		int s = enStudentMsgMapper.selectEnStudentMsgSize(enScorePojo.getStudentId(),DateUtile.toYmd(enScorePojo.getProblemDate()));
		if(s > 0){
			s = 3;
		}
		if(null == ranking){
			ranking = new EnRanking();
			ranking.setStudentId(enScorePojo.getStudentId());
			ranking.setStudentDuration(0);
			ranking.setClasssId(enStudent.getClasssId());
			ranking.setStudentScore((score.getDouble("score")*0.85) + size + s);
			ranking.setStudentAllScore(score.getDouble("allScore"));
			enRankingMapper.insertEnRanking(ranking);
			return;
		}
		ranking.setStudentScore((score.getDouble("score")*0.85) + size + s);
		ranking.setStudentAllScore(score.getDouble("allScore"));
		enRankingMapper.updateEnRanking(ranking);
	}

	/**
	 * 修改成绩
	 */
	@Override
	@Transactional
	public void updateEnScoreStudent(EnScore score) {
		RequestUtile.getLoginUserId();
		EnScore enScorePojo = enScoreMapper.selectEnScoreByScoreId(score.getScoreId());
		if(null == enScorePojo){
			throw new SysException("试题不存在或已被删除!");
		}
		enScorePojo.setScore(score.getScore());
		enScoreMapper.updateEnScore(enScorePojo);
	}

	/**
	 * 修改成绩
	 */
	@Override
	@Transactional
	public void deleteEnScoreStudent(EnScore score) {
		RequestUtile.getLoginUserId();
		enScoreMapper.deleteEnScore(score.getScoreId());
		enScoreMapper.deleteEnScoreAnswer(score.getScoreId());
	}

	/**
	 * 查询成绩详情
	 */
	@Override
	public EnScore selectEnScoreByScoreId(String scoreId){
		EnScore score = enScoreMapper.selectEnScoreByScoreId(scoreId);
		if(null == score){
			throw new SysException("试题不存在或已被删除!");
		}
		JSONObject json = new JSONObject();
		json.put("scoreId",score.getScoreId());
		json.put("problemDate",score.getProblemDate());
		switch (score.getProblemUpType()){
			case "1": score.setProblem(enHearingService.selectEnHearing(json));break;
			case "2": score.setProblem(enParagraphService.selectEnParagraph(json));break;
//			case "3": score.setProblem(enParagraphService.selectEnParagraphCH(json));break;
			case "4": score.setProblem(enHearingService.selectEnHearingKy(json));break;
			case "5":
			case "6": score.setProblem(enParagraphService.selectEnParagraph56(json));break;
		}
		return score;
	}

	/**
	 * 查询成绩列表
	 */
	@Override
	public PageList<EnScore> selectEnScoreByList(JSONObject json){
		return enScoreMapper.selectEnScoreByList(json);
	}

	/**
	 * 分页查询成绩列表
	 */
	@Override
	public PageList<EnScore> selectEnScoreByPage(JSONObject json){
		return enScoreMapper.selectEnScoreByList(StrUtile.getPageJson(json));
	}

	/**
	 * 查询本周答题情况1
	 */
	@Override
	public JSONObject selectEnScoreStudent(JSONObject json){
		json.put("problemDateT","1");
		json.put("studentId", RequestUtile.getLoginUserId());
		List<EnScore> scoreList = enScoreMapper.selectEnScoreByList(json).getList();
		JSONObject data = new JSONObject();
		data.put("completed",scoreList.stream().filter(s->"2".equals(s.getScoreState())).collect(Collectors.toList()));
		data.put("afoot",scoreList.stream().filter(s->"1".equals(s.getScoreState())).collect(Collectors.toList()));
		return data;
	}
}